﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;

using System.Drawing.Drawing2D;

using System.IO;
using IrisGenerator.Framework.Events;
using System.Reflection;
using IrisGenerator.Resources;

namespace IrisGenerator.Common.Core.UI
{
    public class VerticalMenu<T> : Control
    {

        #region Events

        public event EventHandler<BaseEventArgs<T>> ItemClicked;
        

        #endregion

        #region .ctor

        public VerticalMenu()
            : base()
        {
            SetStyle(ControlStyles.AllPaintingInWmPaint |
                    ControlStyles.OptimizedDoubleBuffer |
                    ControlStyles.ResizeRedraw |
                    ControlStyles.UserPaint, true);

            this.Cursor = Cursors.Hand;
            
        }

        #endregion

        #region Fields

        public List<VerticalMenuItem<T>> Items
        {
            get
            {
                if (_items == null)
                    _items = new List<VerticalMenuItem<T>>();
                return _items;
            }
        }
        private List<VerticalMenuItem<T>> _items;
        
        #endregion

        
        #region Methods

        private void RefreshList()
        {
            if (_items == null)
                _items = new List<VerticalMenuItem<T>>();
            _items.Clear();
            

            this.Height = _items.Count * 37 + 37;
        }

        private void SetHeight()
        {
            int tmp = this.Items.Count * 37 + 37;
            if (!tmp.Equals(this.Height))
                this.Height = tmp;
        }



        private void DrawItem(Graphics g, int yOffset, VerticalMenuItem<T> item)
        {
            Bitmap img = null;

            Rectangle bg = new Rectangle(0, yOffset, this.Width - 1, 36);
            Rectangle fg = new Rectangle(5, yOffset, this.Width - 6, 36);
            SolidBrush lgb;

            item.ClipRectangle = bg;

            if (item.Hover)
                lgb = new SolidBrush(SystemColors.Info);
            else if (item.Selected)
                lgb = new SolidBrush(SystemColors.ControlDark);
            else
                lgb = new SolidBrush(SystemColors.ControlLight);
            g.FillRectangle(lgb, bg);


            
            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Near;
            sf.LineAlignment = StringAlignment.Center;
            g.DrawString(item.Value as string, this.Font, new SolidBrush(this.ForeColor),
                fg, sf);

        }

        private void DrawHeader(Graphics g)
        {
            Bitmap img;
            Stream s = typeof(ResourceManager).Assembly.GetManifestResourceStream("IrisGenerator.Resources.24px-Project.png");


            Rectangle bg = new Rectangle(0, 0, this.Width - 1, 36);
            Rectangle fg = new Rectangle(5, 0, this.Width - 6, 36);

            LinearGradientBrush lgb = new LinearGradientBrush(
                bg, SystemColors.InactiveCaption, SystemColors.GradientInactiveCaption,
                LinearGradientMode.Horizontal);

            g.FillRectangle(lgb, bg);



            if (s != null)
            {
                img = new Bitmap(s);
                if (img.Height > 32)
                    bg = new Rectangle(0, 0, this.Width - 1, img.Height + 4);

                fg = new Rectangle(img.Width + 10, 0, this.Width - img.Width - 11, 36);

                int top = (36 - img.Height) / 2;
                if (top < 0)
                    top = 0;
                g.DrawImage(img, 5, top);
            }

            StringFormat sf = new StringFormat();
            sf.Alignment = StringAlignment.Near;
            sf.LineAlignment = StringAlignment.Center;
            g.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor),
                fg, sf);

            g.DrawLine(new Pen(SystemColors.InactiveBorder),
                new Point(bg.Left, bg.Bottom), new Point(bg.Right, bg.Bottom));
        }

        protected void OnItemClicked(VerticalMenuItem<T> m)
        {
            if (ItemClicked != null)
                ItemClicked(this,new BaseEventArgs<T>(m.Value,false));
        }

        #endregion

        #region Parent events handling

        void Parent_Resize(object sender, EventArgs e)
        {
            if (this.Parent == null || this.Parent.Margin == null || this.Parent.Padding == null ||
                (this.Parent.Width - this.Parent.Margin.Horizontal - this.Parent.Padding.Horizontal < 0)
                )
                this.Width = 0;
            else
                this.Width = this.Parent.Width - this.Parent.Margin.Horizontal - this.Parent.Padding.Horizontal;
        }

        #endregion

        #region Overrided events


        protected override void OnResize(EventArgs e)
        {
            if (this._items == null)
                this._items = new List<VerticalMenuItem<T>>();
            this.Height = _items.Count * 37 + 37;
            if (this.Width < 10)
                this.Width = 10;
            base.OnResize(e);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            SetHeight();
            DrawHeader(e.Graphics);

            int yOffset = 37;
            Rectangle full = new Rectangle(0, 0, this.Width - 1, this.Height - 1);

            foreach(VerticalMenuItem<T> item in this.Items)
            {
                DrawItem(e.Graphics, yOffset, item);
                yOffset += 37;
            }

            //if (Engine != null)
            //{
            //    DrawHeader(e.Graphics);
            //    Rectangle full = new Rectangle(0, 0, this.Width - 1, this.Height - 1);


            //    int yOffset = 37;

            //    foreach (ModuleListItem m in _items)
            //    {
            //        DrawItem(e.Graphics, yOffset, m);
            //        yOffset += 37;
            //    }
            //    //Engine.SetState();
            //    e.Graphics.DrawRectangle(new Pen(SystemColors.InactiveBorder), full);

            //}
        }

        protected override void OnMouseMove(MouseEventArgs e)
        {
            
            foreach (VerticalMenuItem<T> it in _items)
            {
                if (it.ClipRectangle.Contains(e.X, e.Y))
                    it.Hover = true;
                else
                    it.Hover = false;
            }
            this.Invalidate();
        }

        protected override void OnClick(EventArgs e)
        {
            
            bool selected = false;
            foreach (VerticalMenuItem<T> item in this.Items)
            {
                if (item.Hover)
                {
                    item.Selected = true;
                    selected = true;
                    OnItemClicked(item);
                }
                else
                    item.Selected = false;
            }

            if (!selected)
            {
                base.OnClick(e);
                selected = false;
            }

            this.Invalidate();
        }

        protected override void OnParentChanged(EventArgs e)
        {

            this.Width = this.Parent.Width - this.Parent.Margin.Horizontal - this.Parent.Padding.Horizontal;
            this.Parent.Resize += new EventHandler(Parent_Resize);
            this.Dock = DockStyle.Top;
            this.Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            //if (_items == null)
            //    return;
            //foreach (ModuleListItem item in _items)
            //    item.Hover = false;
            //this.Invalidate();
        }

        #endregion

    }
}
